#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define LAKE_SIZE 100
#define DIAMETER 15
#define MAX_NODES 102

typedef _Bool Graph;
typedef struct POSITION Position;
typedef Position ElementType;
typedef struct MINHEAP MinHeap;
typedef struct QUEUE Queue;
typedef struct STACK Stack;
struct STACK{
	int elm;
	Stack *next;
};
struct POSITION{
	double x;
	double y;
};
struct MINHEAP {
	ElementType *elm;
	int size;
	int capacity;
};
struct QUEUE{
	ElementType elm;
	Queue *next;
	Queue *tail;
};
double DistToIsland(Position);
double DistBetCros(Position,Position);
double DistToBank(Position);
MinHeap* HeapInit(int);
void Add(MinHeap*,ElementType);
ElementType Delete(MinHeap*);
void MakeHeap(MinHeap*,int (*)(ElementType,ElementType));
void HeapSort(MinHeap*,int (*)(ElementType,ElementType));
int CompareElm(ElementType,ElementType);
Queue *QueueInit(void);
_Bool QueueEmpty(Queue*);
void EnQueue(Queue*,ElementType);
ElementType DeQueue(Queue*);
Stack *StackInit(void);
_Bool StackEmpty(Stack *s);
void Push(Stack *s,int e);
int Pop(Stack *s);
//return the number of shortest path
//int Dijkstra(int n,Graph(*graph)[n],Queue *q,int start,int end);
int Dijkstra(int n,Graph(*graph)[n],Stack *s,int start,int end);
int BFS(int n,Graph(*graph)[n],Stack *s,int start,int end);

int main(){
	int N,D;
	scanf("%d %d",&N,&D);
	Position p[100];
	for(int i=0;i<N;i++){
		scanf("%lf %lf",&p[i].x,&p[i].y);
	}
	MinHeap *h=HeapInit(100);
	memcpy(&h->elm[1],p,sizeof(ElementType)*N);
	h->size=N;
	MakeHeap(h,CompareElm);
	HeapSort(h,CompareElm);
//double DistToIsland(Position);
//double DistBetCros(Position,Position);
//double DistToBank(Position);
	Graph g[N+2][N+2];
	for(int i=0;i<N+2;i++)g[i][i]=false;
	for(int i=1;i<=N;i++){
		for(int j=i+1;j<=N;j++){
			if(	DistBetCros(h->elm[i],h->elm[j]) <= D ){
				g[i][j]=g[j][i]=true;
			}else{
				g[i][j]=g[j][i]=false;
			}
		}
	}
	// index 0 for island ; index n+1 for bank;
	for(int i=1;i<=N;i++){
		if( DistToIsland(h->elm[i]) <= D )
			g[0][i]=g[i][0]=true;
		else
			g[0][i]=g[i][0]=false;
	}
	for(int i=1;i<=N;i++){
		if( DistToBank(h->elm[i]) <= D )
			g[N+1][i]=g[i][N+1]=true;
		else
			g[N+1][i]=g[i][N+1]=false;
	}
	if( D >= 42.5 ){
		g[N+1][0]=g[0][N+1]=true;
	}else{
		g[N+1][0]=g[0][N+1]=false;
	}

//for(int i=0;i<=N+1;i++){
//	for(int j=0;j<=N+1;j++){
//		printf("%3d",g[i][j]?1:0);
//	}
//	printf("\n");
//}
	Stack *s=StackInit();
	//int a=Dijkstra(N+2,g,s,0,N+1);
	int a=BFS(N+2,g,s,0,N+1);
	if( -1 == a ){
		printf("0");
	}else{
		printf("%d\n",a);
		while( !StackEmpty(s) ){
			a=Pop(s);
			printf("%d %d\n",(int)h->elm[a].x,(int)h->elm[a].y);
		}
	}
	return 0;
}

MinHeap* HeapInit(int capacity){
	MinHeap *ret=malloc(sizeof(MinHeap));
	ret->elm=malloc(sizeof(ElementType)*(1+capacity));
	ret->elm[0].x=0.0;
	ret->elm[0].y=0.0;
	ret->size=0;
	ret->capacity=capacity;
	return ret;
}

int CompareElm(ElementType elm1,ElementType elm2){
	if( (elm1.x*elm1.x+elm1.y*elm1.y) > (elm2.x*elm2.x+elm2.y*elm2.y) )
		return 1;
	else if( (elm1.x*elm1.x+elm1.y*elm1.y) == (elm2.x*elm2.x+elm2.y*elm2.y) )
		return 0;
	else
		return -1;
}
void Add(MinHeap *h,ElementType elm){
	int i=++h->size;
	while( CompareElm(h->elm[i/2],elm) > 0 ){
		h->elm[i]=h->elm[i/2];
		i=i/2;
	}
	h->elm[i]=elm;
	return ;
}
ElementType Delete(MinHeap *h){
	ElementType ret=h->elm[1];
	ElementType e=h->elm[h->size--];
	int i=1;
	while( 2*i <= h->size ){
		if( 2*i<h->size && CompareElm(h->elm[2*i],h->elm[2*i+1])>0 && CompareElm(e,h->elm[2*i+1])>0 ){
			h->elm[i]=h->elm[2*i+1];
			i=2*i+1;
		}else if( CompareElm(h->elm[2*i],e)<0 ){
			h->elm[i]=h->elm[2*i];
			i=2*i;
		}else{
			break;
		}
	}
	h->elm[i]=e;
	return ret;
}
void MakeHeap(MinHeap *h,int (*cmp)(ElementType,ElementType)){
	int start=h->size/2;
	for(int i=start;i>0;i--){
		int s=i;
		ElementType tmp=h->elm[s];
		while( 2*s <= h->size ){
			if( 2*s < h->size && cmp(h->elm[2*s],h->elm[2*s+1]) > 0 \
				&& cmp(h->elm[2*s+1],tmp) < 0 ){
				h->elm[s]=h->elm[2*s+1];
				s=2*s+1;
			}
			else if( cmp(tmp,h->elm[2*s]) > 0 ){
				h->elm[s]=h->elm[2*s];
				s=2*s;
			}else{
				break;
			}
		}
		h->elm[s]=tmp;
	}
	return;
}
void HeapSort(MinHeap *h,int (*cmp)(ElementType,ElementType)){
	ElementType e;
	int size=h->size;
	while( size ){
		e=h->elm[size];
		h->elm[size--]=h->elm[1];
		int i=1;
		while( 2*i <= size ){
			if( 2*i<size && cmp(h->elm[2*i],h->elm[2*i+1])>0 && cmp(e,h->elm[2*i+1])>0 ){
				h->elm[i]=h->elm[2*i+1];
				i=2*i+1;
			}else if( cmp(h->elm[2*i],e)<0 ){
				h->elm[i]=h->elm[2*i];
				i=2*i;
			}else{
				break;
			}
		}
		h->elm[i]=e;
	}
	for(int i=1;i<=h->size/2;i++){
		e=h->elm[h->size+1-i];
		h->elm[h->size+1-i]=h->elm[i];
		h->elm[i]=e;
	}
	return;
}
double Pow(double f,int n){
	double ret=1.0;
	for(int i=0;i<n;i++)
		ret*=f;
	return ret;
}
double Abs(double f){
	if( f > 0.0 )
		return f;
	else
		return -f;
}
double DistToIsland(Position p){
	return sqrt(Pow(p.x,2)+Pow(p.y,2))-DIAMETER/2;
}
double DistBetCros(Position p1,Position p2){
	//return sqrt(Abs(Pow(p1.x,2)+Pow(p1.y,2)-Pow(p2.x,2)-Pow(p2.y,2)));
	return sqrt( Pow(Abs(p1.x-p2.x),2) + Pow(Abs(p1.y-p2.y),2) );
}
double DistToBank(Position p){
	double w=Abs(p.x)>Abs(p.y)?Abs(p.x):Abs(p.y);
	return LAKE_SIZE/2-w;
}
Queue *QueueInit(void){
	Queue *q=malloc(sizeof(Queue));
	q->next=NULL;
	q->tail=q;
	return q;
}
_Bool QueueEmpty(Queue *q){
	if( q->next )
		return false;
	return true;
}
void EnQueue(Queue *q,ElementType elm){
	Queue *new=malloc(sizeof(Queue));
	new->next=NULL;
	new->elm=elm;
	q->tail->next=new;
	q->tail=new;
	return;
}
ElementType DeQueue(Queue *q){
	ElementType ret=q->next->elm;
	Queue *tmp=q->next;
	q->next=q->next->next;
	free(tmp);
	if( !q->next )
		q->tail=q;
	return ret;
}

typedef struct HEAP Heap;
typedef struct HEAPNODE HNode;
struct HEAPNODE{
	int index;
	int dis;
};
struct HEAP {
	HNode *elm;
	int size;
	int capacity;
};
Heap* initH(int capacity){
	Heap *ret=malloc(sizeof(Heap));
	ret->elm=malloc(sizeof(HNode)*(capacity+1));
	ret->elm[0].dis=INT_MIN;
	ret->size=0;
	ret->capacity=capacity;
	return ret;
}
_Bool heapEty(Heap *h){
	if( h->size )return false;
	return true;
}
_Bool heapFl(Heap *h){
	if( h->size == h->capacity )return true;
	return false;
}
void inHeap(Heap *h,HNode elm){
	int i=++h->size;
	while( elm.dis < h->elm[i/2].dis ){
		h->elm[i]=h->elm[i/2];
		i=i/2;
	}
	h->elm[i]=elm;
	return;
}
HNode outHeap(Heap *h){
	HNode ret=h->elm[1];
	HNode e=h->elm[h->size--];
	int i=1;
	while( 2*i <= h->size ){
		if( 2*i < h->size && h->elm[2*i].dis>h->elm[2*i+1].dis && e.dis > h->elm[2*i+1].dis ){
			h->elm[i]=h->elm[2*i+1];
			i=2*i+1;
		}else if( h->elm[2*i].dis < e.dis ){
			h->elm[i]=h->elm[2*i];
			i=2*i;
		}else{
			break;
		}
	}
	h->elm[i]=e;
	return ret;
}

//Heap* initH(int capacity){
//_Bool heapEty(Heap *h){
//_Bool heapFl(Heap *h){
//void inHeap(Heap *h,int elm){
//int outHeap(Heap *h){
Stack *StackInit(void){
	Stack *s=malloc(sizeof(Stack));
	s->next=NULL;
	return s;
}
_Bool StackEmpty(Stack *s){
	if( s->next )return false;
	return true;
}
void Push(Stack *s,int e){
	Stack *new=malloc(sizeof(Stack));
	new->elm=e;
	new->next=s->next;
	s->next=new;
	return;
}
int Pop(Stack *s){
	int ret=s->next->elm;
	Stack *t=s->next;
	s->next=s->next->next;
	free(t);
	return ret;
}
int Dijkstra(int n,Graph(*graph)[n],Stack *s,int start,int end){
	_Bool collect[n];
	int dis[n];
	int path[n];
	for(int i=0;i<n;i++){
		collect[i]=false;
		dis[i]=INT_MAX;
		path[i]=-1;
	}
	dis[start]=0;
	Heap *h=initH(MAX_NODES);
	inHeap(h,(HNode){.index=start,.dis=dis[start]});
	HNode e;
	while( !heapEty(h) ){
		e=outHeap(h);
printf("OutHeap:%d %d\n",e.index,e.dis);
		collect[e.index]=true;
		for(int i=0;i<n;i++){
			if( graph[e.index][i] && !collect[i] && dis[i]>dis[e.index]+1 ){
				dis[i]=dis[e.index]+1;
				path[i]=e.index;
				inHeap(h,(HNode){.index=i,.dis=dis[i]});
printf("InHeap:%d %d\n",i,dis[i]);
			}
		}
	}
	int x=path[end];
	while( path[x] != -1 ){
		Push(s,path[x]);
		x=path[x];
	}
printf("\nIndex\n");
for(int i=0;i<n;i++)printf("%7d ",i);
printf("\nCollect\n");
for(int i=0;i<n;i++)printf("%7d ",collect[i]?1:0);
printf("\nPath\n");
for(int i=0;i<n;i++)printf("%7d ",path[i]);
	return dis[end];
}
typedef struct QUE Que;
struct QUE{
	int elm;
	Que *next;
	Que *tail;
};
Que *QueInit(void);
_Bool QueEmpty(Que*);
void EnQue(Que*,int);
int  DeQue(Que*);
Que *QueInit(void){
	Que *q=malloc(sizeof(Que));
	q->next=NULL;
	q->tail=q;
	return q;
}
_Bool QueEmpty(Que *q){
	if( q->next )
		return false;
	return true;
}
void EnQue(Que *q,int e){
	Que *new=malloc(sizeof(Que));
	new->elm=e;
	new->next=NULL;
	q->tail->next=new;
	q->tail=new;
	return;
}
int  DeQue(Que *q){
	int ret=q->next->elm;
	Que *t=q->next;
	q->next=q->next->next;
	free(t);
	if( !q->next )
		q->tail=q;
	return ret;
}
//Que *QueInit(void);
//void EnQue(Que*,int);
//int  DeQue(Que*);
int BFS(int n,Graph(*graph)[n],Stack *s,int start,int end){
	int dis[n],path[n];
	_Bool visited[n];
	for(int i=0;i<n;i++){
		dis[i]=INT_MAX;
		path[i]=-1;
		visited[i]=false;
	}
	Que *q=QueInit();
	EnQue(q,start);
	dis[start]=0;
	int e;
	while( !QueEmpty(q) ){
		e=DeQue(q);
		visited[e]=true;
		for(int i=0;i<n;i++){
			if( graph[e][i] && !visited[i] && dis[i]>dis[e]+1 ){
				dis[i]=dis[e]+1;
				path[i]=e;
				EnQue(q,i);
			}
		}
	}
	int x=path[end];
	if( -1 == x )return -1;
	while( path[x] != -1 ){
		Push(s,x);
		x=path[x];
	}
	return dis[end];
}
